/**
 * 
 */
package com.javassist.examples;

import java.lang.reflect.Method;

import org.apache.commons.lang.StringUtils;

import javassist.ClassPool;
import javassist.CtClass;
import javassist.CtField;
import javassist.CtMethod;
import javassist.CtNewMethod;

/**
 * TestSimpleVO.java. 2011-12-26下午2:52:16 @author LionBule.
 */
public class TestSimpleVO {

    public static void main(String[] args) throws Exception {
        ClassPool cpool = ClassPool.getDefault();

        CtClass cc = cpool.makeClass("User");

        //name
        String fieldName = "name";
        String setMethodName = "set" + StringUtils.capitalize(fieldName);
        String getMethodName = "get" + StringUtils.capitalize(fieldName);

        //age
        String fieldAge = "age";
        String setMethodAge = "set" + StringUtils.capitalize(fieldAge);
        String getMethodAge = "get" + StringUtils.capitalize(fieldAge);
        
        //field
        CtField nameField = CtField.make("private String name;", cc);
        cc.addField(nameField);

        CtField ageField = CtField.make("private int age;", cc);
        cc.addField(ageField);

        //methods
        CtMethod nameSetter = CtNewMethod.setter(setMethodName, nameField);
        cc.addMethod(nameSetter);
        CtMethod nameGetter = CtNewMethod.getter(getMethodName, nameField);
        cc.addMethod(nameGetter);

        CtMethod ageSetter = CtNewMethod.setter(setMethodAge, ageField);
        cc.addMethod(ageSetter);
        CtMethod ageGetter = CtNewMethod.getter(getMethodAge, ageField);
        cc.addMethod(ageGetter);
        
        Class<?> userClass = cc.toClass();
        Method[] tempMethods = userClass.getMethods();
        for (Method m : tempMethods) {
            System.out.println(m.getName());
        }

        //invoker
        Object user = userClass.newInstance();

        
        //name
        Method setMethod = userClass.getMethod(setMethodName, new Class[] { String.class });
        setMethod.invoke(user, new Object[] { new String("123456789") });
        Method getMethod = userClass.getMethod(getMethodName, new Class[] {});
        System.out.println(getMethod.invoke(user, new Object[] {}));

        //age
        Method setMethodage = userClass.getMethod(setMethodAge, new Class[] { int.class });
        setMethodage.invoke(user, new Object[] {89});
        Method getMethodage = userClass.getMethod(getMethodAge, new Class[] {});
        System.out.println(getMethodage.invoke(user, new Object[] {}));       
    }

    // type/fieldName
    final static String fieldTemplate = "private %s %s";
    // type/getXxx/fieldName
    final static String getTemplate = "public %s %s() { return %s; }";
    // setXxx/type/fieldName/fieldName/fieldName
    final static String setTemplate = "public void %s(%s %s) { this.%s = %s; }";

    public static String setter(String type, String fieldName) {
        String setMethodName = "set" + StringUtils.capitalize(fieldName);
        return String.format(setTemplate, setMethodName, type, fieldName, fieldName, fieldName);
    }

    public static String getter(String type, String fieldName) {
        String getMethodName = "get" + StringUtils.capitalize(fieldName);
        return String.format(getTemplate, type, getMethodName, fieldName);
    }

    
    
}
